package deepbrain.iit.util;

import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Collection;
import java.util.List;

import deepbrain.iit.PhiComputation;
import deepbrain.simnetwork.exception.SimNetworkRuntimeException;
import deepbrain.simnetwork.loader.NetworkLoader;
import deepbrain.simnetwork.loader.xml.XmlNetworkLoader;
import deepbrain.simnetwork.mechanism.Mechanism;
import deepbrain.simnetwork.network.Network;
import deepbrain.simnetwork.network.NetworkState;
import deepbrain.simnetwork.util.SimNetUtils;

public class IITUtility {

	public static final void compPHIforState(String networkFilePath,
			NetworkState state, Mechanism mechanism) {
		compPHIforState(networkFilePath, state, mechanism, 2);
	}

	public static final void compPHIforState(String networkFilePath,
			NetworkState state, Mechanism mechanism, int n_part) {
		try {
			NetworkLoader networkLoader = new XmlNetworkLoader(networkFilePath);
			Network network = networkLoader.loadNetwork();
			if (mechanism != null)
				network.setMechanism(mechanism);

			PhiComputation phi = new PhiComputation(network);
			System.out.println(state);
			System.out.println(phi.findMIP(state, n_part));
		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

	public static final void compPHIforStates(String networkFilePath,
			Collection<NetworkState> states, Mechanism mechanism) {
		compPHIforStates(networkFilePath, states, mechanism, 2);
	}

	public static final void compPHIforStates(String networkFilePath,
			Collection<NetworkState> states, Mechanism mechanism, int n_part) {
		try {
			NetworkLoader networkLoader = new XmlNetworkLoader(networkFilePath);
			Network network = networkLoader.loadNetwork();
			if (mechanism != null)
				network.setMechanism(mechanism);

			PhiComputation phi = new PhiComputation(network);
			for (NetworkState state : states) {
				System.out.println(state);
				System.out.println(phi.findMIP(state, n_part));
			}

		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

	public static final void compPHIforAllStates(String networkFilePath,
			Mechanism mechanism) {
		compPHIforAllStates(networkFilePath, mechanism, System.out);
	}

	public static final void compPHIforAllStates(String networkFilePath,
			Mechanism mechanism, String outputPath) {
		try {
			PrintStream writer = new PrintStream(outputPath);
			compPHIforAllStates(networkFilePath, mechanism, writer);
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static final void compPHIforAllStates(String networkFilePath,
			Mechanism mechanism, PrintStream writer) {
		long startTime = System.currentTimeMillis();
		compPHIforAllStates(networkFilePath, mechanism, 2, writer);
		writer.println("Used time: " + (System.currentTimeMillis() - startTime)
				+ "ms");
	}

	public static final void compPHIforAllStates(String networkFilePath,
			Mechanism mechanism, int n_part, PrintStream writer) {
		try {
			NetworkLoader networkLoader = new XmlNetworkLoader(networkFilePath);
			Network network = networkLoader.loadNetwork();
			if (mechanism != null)
				network.setMechanism(mechanism);

			List<NetworkState> states = SimNetUtils
					.getAllCertainNetworkStates(network.getNumOfNodes());

			PhiComputation phi = new PhiComputation(network);
			for (NetworkState state : states) {
				writer.println(state.toStringBrief());
				writer.println(phi.findMIP(state, n_part));
			}

		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}
	
	public static final void compPHIforAllStates(String networkFilePath,
			Mechanism mechanism, int n_part) {
		try {
			NetworkLoader networkLoader = new XmlNetworkLoader(networkFilePath);
			Network network = networkLoader.loadNetwork();
			if (mechanism != null)
				network.setMechanism(mechanism);

			List<NetworkState> states = SimNetUtils
					.getAllCertainNetworkStates(network.getNumOfNodes());

			PhiComputation phi = new PhiComputation(network);
			for (NetworkState state : states) {
				System.out.println(state.toStringBrief());
				System.out.println(phi.findMIP(state, n_part));
			}

		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

	public static final void compPHIforAllStates(String networkFilePath,
			Mechanism mechanism, int n_part, String outputPath) {
		try {
			compPHIforAllStates(networkFilePath, mechanism, n_part,
					new PrintStream(outputPath));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

}
